package server

import (
	"cloud-entropy-storage-system/server/internal/core/client"
	status2 "cloud-entropy-storage-system/server/internal/core/status"
	"fmt"
	"github.com/alexeyco/simpletable"
	"sync"
	"time"
)

var (
	storageChan chan *status2.StorageStatus
	manager     *Manager
)

func AddStorage(ss *status2.StorageStatus) {
	storageChan <- ss
}

// Manager  服务端 负责api及rpc中心。接收rpc心跳并检测是否初始化
type Manager struct {
	ShowList    bool
	lock        sync.Mutex
	storageList []*status2.StorageStatus
	volMaps     map[uint64]*status2.VolumeStatus
}

func NewServer() *Manager {
	if manager == nil {
		manager = new(Manager)
		manager.volMaps = make(map[uint64]*status2.VolumeStatus)
		manager.storageList = make([]*status2.StorageStatus, 0, 1)
		storageChan = make(chan *status2.StorageStatus)
		go manager.checkStorage()
	}
	return manager
}

func (s *Manager) checkStorage() {
	for {
		select {
		case sc := <-storageChan:
			has := false
			for k, storage := range s.storageList {
				if storage.Machine == sc.Machine {
					has = true
					s.storageList[k] = sc // 已存在此storage，更新时间戳
				}
			}
			if !has {
				s.storageList = append(s.storageList, sc) // 不存在此storage，新增
			}
			for _, v := range sc.Volumes { // 不管存不存在 都更新一下volume map
				s.volMaps[v.Vid] = &status2.VolumeStatus{
					Vid:           v.Vid,
					Writable:      v.Writable,
					StorageStatus: sc,
				}
			}
			if s.ShowList {
				s.showCMD()
			}
		}
		time.Sleep(time.Millisecond * 300)
	}
}

func (s *Manager) GetVolume(vid uint64) *status2.VolumeStatus {
	if val, ok := s.volMaps[vid]; ok {
		return val
	}
	return nil
}

func (s *Manager) GetStorageConn() *client.UploadClient {
	s.lock.Lock()
	defer s.lock.Unlock()
	if len(s.volMaps) > 0 {
		for _, v := range s.volMaps {
			if v.StorageStatus.IsAlive() && v.StorageStatus.Writeable && v.Writable {
				return client.NewUploadClient(v.StorageStatus.RpcConn)
			}
		}
	}
	return nil
}

func (s *Manager) showCMD() {
	fmt.Println()
	fmt.Println()

	table := simpletable.New()
	table.Header = &simpletable.Header{
		Cells: []*simpletable.Cell{
			{Align: simpletable.AlignCenter, Text: "#"},
			{Align: simpletable.AlignCenter, Text: "服务器名称"},
			{Align: simpletable.AlignCenter, Text: "服务器状态"},
			{Align: simpletable.AlignCenter, Text: "存储块占用"},
			{Align: simpletable.AlignCenter, Text: "磁盘使用率"},
			{Align: simpletable.AlignCenter, Text: "磁盘剩余容量"},
		},
	}
	for k, row := range s.storageList {
		r := []*simpletable.Cell{
			{Align: simpletable.AlignRight, Text: fmt.Sprintf("%d", k+1)},
			{Align: simpletable.AlignCenter, Text: row.Machine},
			{Align: simpletable.AlignCenter, Text: row.IsAliveStr()},
			{Align: simpletable.AlignCenter, Text: row.VolumeUsed()},
			{Align: simpletable.AlignCenter, Text: row.DiskUsagePer()},
			{Align: simpletable.AlignCenter, Text: row.GetSize(row.DiskFree)},
		}

		table.Body.Cells = append(table.Body.Cells, r)
	}

	table.Footer = &simpletable.Footer{
		Cells: []*simpletable.Cell{
			{},
			{},
			{},
			{},
			{Align: simpletable.AlignRight, Text: "当前连接storage服务器数量"},
			{Align: simpletable.AlignRight, Text: fmt.Sprintf("%d", len(s.storageList))},
		},
	}

	table.SetStyle(simpletable.StyleCompactLite)
	fmt.Println(table.String())
}
